var SysAutocomplete = function () {
  var template = /* html */ `
    <el-autocomplete class="sys-autocomplete" v-model="showValue" :value-key="valueKey" :placeholder="placeholder" :size="size"
      :placement="placement" :disabled="disabled" :fetch-suggestions="getSuggestionData" @change="handleChange" @blur="handleBlur">
      <template slot-scope="scope" v-if="hasSlot">
        <slot :item="scope.item"></slot>
      </template>
    </el-autocomplete>
  `;

  return {
    props: {
      value: {
        type: String,
        required: true
      },
      valueKey: {
        type: String,
        default: "value"
      },
      options: {
        type: Array,
        default: function () {
          return [];
        }
      },
      openAllDropdown: {
        type: Boolean,
        default: false
      },
      fetchSuggestions: Function,
      size: String,
      placement: String,
      disabled: Boolean,
      placeholder: String
    },

    data: function () {
      return {
        showValue: this.value,
        inputValue: null,
        hasShowAllOption: this.openAllDropdown
      };
    },

    watch: {
      value: function () {
        if (this.inputValue !== null) {
          this.inputValue = null;
          return;
        }
        this.showValue = this.value;
      }
    },

    computed: {
      hasSlot: function () {
        return this.$slots.default || this.$scopedSlots.default;
      }
    },

    methods: {
      getSuggestionData: function (queryStr, cb) {
        var fetchSuggestions = this.fetchSuggestions;
        var hasShowAllOption = this.hasShowAllOption;
        if (fetchSuggestions !== undefined) {
          fetchSuggestions(queryStr, cb, hasShowAllOption);
          if (hasShowAllOption) {
            this.hasShowAllOption = false;
          }
          return;
        }

        var options = this.options;
        if (SysUtil.isEmpty(options)) {
          options = [];
        }
        if (hasShowAllOption) {
          this.hasShowAllOption = false;
          queryStr = '';
        }
        var data = [];
        if (options.length !== 0) {
          var valueKey = this.valueKey;
          var type = typeof options[0];
          queryStr = queryStr.toLocaleLowerCase();
          if (type !== 'object') {
            if (queryStr !== '') {
              data = _.filter(options, function (str) {
                if (typeof str === 'string') {
                  str = str.toLocaleLowerCase();
                } else {
                  str = str + '';
                }
                return str.indexOf(queryStr) !== -1;
              });
            } else {
              data = options;
            }
            data = _.map(data, function (str) {
              var obj = {};
              obj[valueKey] = str;
              return obj;
            });
          } else {
            if (queryStr !== '') {
              data = _.filter(options, function (obj) {
                var str = obj[valueKey];
                if (str === undefined || str === null) {
                  return false;
                }
                str += "";
                str = str.toLocaleLowerCase();
                return str.indexOf(queryStr) !== -1;
              });
            } else {
              data = _.cloneDeep(options);
            }
          }
        }
        cb(data);
      },

      handleChange: function () {
        var showValue = this.showValue;
        if (this.value === showValue) {
          return;
        }

        this.inputValue = showValue;
        this.$emit('input', showValue);
        this.$emit('change', showValue);
      },

      handleBlur: function () {
        if (this.openAllDropdown) {
          this.hasShowAllOption = true;
        }
      }
    },

    template: template
  };
}();

var SysAutocompleteNumber = function () {
  var template = /* html */ `
    <sys-autocomplete :open-all-dropdown="openAllDropdown" v-model="showValue" :options="options"
      :value-key="valueKey" :size="size" :placeholder="placeholder" @change="valueChange">
      <template slot-scope="scope" v-if="hasSlot">
        <slot :item="scope.item"></slot>
      </template>
    </sys-autocomplete>
  `;

  return {
    props: {
      value: {
        required: true
      },
      openAllDropdown: Boolean,
      options: Array,
      valueKey: String,
      size:String,
      min: Number,
      max: Number,
      precision: Number,
      placeholder: String,
      isDecimalZero: {
        type: Boolean,
        default: false
      }
    },

    watch: {
      value: function (val) {
        if (this.inputValue !== null) {
          this.inputValue = null;
          return;
        }

        this.showValue = this.getShowValue(val);
        this.oldValue = val;
      }
    },

    computed: {
      hasSlot: function () {
        return this.$slots.default || this.$scopedSlots.default;
      }
    },

    data: function () {
      return {
        showValue: this.getShowValue(this.value),
        oldValue: this.value,
        inputValue: null
      };
    },

    methods: {
      getShowValue: function (value) {
        if (value === '') {
          return '';
        }

        var precision = this.precision;
        if (precision !== undefined) {
          if (!this.isDecimalZero) {
            return value.toFixed(precision);
          }
        }
        return value;
      },

      valueChange: function () {
        var showValue = this.showValue;
        if (typeof showValue === 'string') {
          showValue = Number(showValue);
        }
        if (isNaN(showValue)) {
          this.resetValue(this.oldValue);
          return;
        }

        var value = this.getValue(showValue);
        this.resetValue(value);
        if (this.value === value) {
          return;
        }

        this.inputValue = value;
        this.oldValue = value;
        this.$emit('input', value);
        this.$emit('change', value);
      },

      resetValue: function (value) {
        var self = this;
        this.$nextTick(function () {
          self.showValue = self.getShowValue(value);
        });
      },

      getValue: function (value) {
        var precision = this.precision;
        if (precision !== undefined) {
          value = _.round(value, precision);
        }

        var min = this.min;
        if (min !== undefined && value < min) {
          value = min;
        }

        var max = this.max;
        if (max !== undefined && value > max) {
          value = max;
        }
        return value;
      }
    },

    components: {
      SysAutocomplete: SysAutocomplete
    },

    template: template
  };
}();
